package com.nuoniu.sibanyun.service.expenses.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.nuoniu.sibanyun.common.constant.OrderConstant;
import com.nuoniu.sibanyun.common.exception.NuoNiuException;
import com.nuoniu.sibanyun.common.lang.DateUtils;
import com.nuoniu.sibanyun.common.lang.StringUtils;
import com.nuoniu.sibanyun.entity.crm.CrmGoodsOrder;
import com.nuoniu.sibanyun.entity.crm.call.dto.AgentOrderDto;
import com.nuoniu.sibanyun.entity.expenses.ExpensesBusinessOrder;
import com.nuoniu.sibanyun.entity.expenses.dto.ExpensesBusinessOrderSearchDto;
import com.nuoniu.sibanyun.mapper.expenses.ExpensesBusinessOrderMapper;
import com.nuoniu.sibanyun.service.crm.call.ICrmCallBaseSettingInfoService;
import com.nuoniu.sibanyun.service.expenses.IExpensesAccountService;
import com.nuoniu.sibanyun.service.expenses.IExpensesBalanceChangeRecordService;
import com.nuoniu.sibanyun.service.expenses.IExpensesBusinessOrderService;
import com.nuoniu.sibanyun.service.expenses.IExpensesPropertyService;
import com.nuoniu.sibanyun.userThread.UserInfo;
import com.nuoniu.sibanyun.userThread.UserThreadLocal;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;

/**
 * <p>
 * 费用中心-业务订单 服务实现类
 * </p>
 *
 * @author 白强
 * @since 2022-05-06
 */
@Service
public class ExpensesBusinessOrderServiceImpl extends ServiceImpl<ExpensesBusinessOrderMapper, ExpensesBusinessOrder> implements IExpensesBusinessOrderService {

    @Autowired
    private IExpensesAccountService accountService;
    @Autowired
    private IExpensesPropertyService propertyService;
    @Autowired
    private IExpensesBalanceChangeRecordService balanceChangeRecordService;
    @Autowired
    @Lazy
    private ICrmCallBaseSettingInfoService callBaseSettingInfoService;

    @Override
    public Page<ExpensesBusinessOrder> pageList(ExpensesBusinessOrderSearchDto businessOrderSearchDto) {
        String businessOrderNo = businessOrderSearchDto.getBusinessOrderNo();
        Integer businessType = businessOrderSearchDto.getBusinessType();
        Boolean isPrdProduction = businessOrderSearchDto.getIsPrdProduction();
        Integer orderType = businessOrderSearchDto.getOrderType();
        Integer paymentType = businessOrderSearchDto.getPaymentType();
        String productionType = businessOrderSearchDto.getProductionType();
        Integer productionId = businessOrderSearchDto.getProductionId();
        String productionName = businessOrderSearchDto.getProductionName();
        Integer status = businessOrderSearchDto.getStatus();
        UserInfo userInfo = UserThreadLocal.get();
        Integer companyId = userInfo.getCompanyId();
        QueryWrapper<ExpensesBusinessOrder> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("company_id",companyId);
        if(StringUtils.isNotBlank(businessOrderNo)){
            queryWrapper.like("business_order_no",businessOrderNo);
        }
        if(null != businessType){
            queryWrapper.eq("business_type",businessType);
        }
        if(null != isPrdProduction){
            queryWrapper.eq("is_prd_production",isPrdProduction);
        }
        if(null != orderType){
            queryWrapper.eq("order_type",orderType);
        }
        if(null != paymentType){
            queryWrapper.eq("payment_type",paymentType);
        }
        if(StringUtils.isNotBlank(productionType)){
            queryWrapper.eq("production_type",productionType);
        }
        if(null != productionId){
            queryWrapper.eq("production_id",productionId);
        }
        if(StringUtils.isNotBlank(productionName)){
            queryWrapper.like("production_name",productionName);
        }
        if(null != status){
            queryWrapper.eq("status",status);
        }
        Page page = page(businessOrderSearchDto.getPage(), queryWrapper);
        return page;
    }

    @Override
    public Page<ExpensesBusinessOrder> sysPageList(ExpensesBusinessOrderSearchDto businessOrderSearchDto) {
        String businessOrderNo = businessOrderSearchDto.getBusinessOrderNo();
        Integer businessType = businessOrderSearchDto.getBusinessType();
        Boolean isPrdProduction = businessOrderSearchDto.getIsPrdProduction();
        Integer orderType = businessOrderSearchDto.getOrderType();
        Integer paymentType = businessOrderSearchDto.getPaymentType();
        String productionType = businessOrderSearchDto.getProductionType();
        Integer productionId = businessOrderSearchDto.getProductionId();
        String productionName = businessOrderSearchDto.getProductionName();
        Integer status = businessOrderSearchDto.getStatus();
        UserInfo userInfo = UserThreadLocal.get();
        Integer companyId = userInfo.getCompanyId();
        QueryWrapper<ExpensesBusinessOrder> queryWrapper = new QueryWrapper<>();
        if(null != businessType){
            queryWrapper.eq("company_id",companyId);
        }
        if(StringUtils.isNotBlank(businessOrderNo)){
            queryWrapper.like("business_order_no",businessOrderNo);
        }
        if(null != businessType){
            queryWrapper.eq("business_type",businessType);
        }
        if(null != isPrdProduction){
            queryWrapper.eq("is_prd_production",isPrdProduction);
        }
        if(null != orderType){
            queryWrapper.eq("order_type",orderType);
        }
        if(null != paymentType){
            queryWrapper.eq("payment_type",paymentType);
        }
        if(StringUtils.isNotBlank(productionType)){
            queryWrapper.eq("production_type",productionType);
        }
        if(null != productionId){
            queryWrapper.eq("production_id",productionId);
        }
        if(StringUtils.isNotBlank(productionName)){
            queryWrapper.like("production_name",productionName);
        }
        if(null != status){
            queryWrapper.eq("status",status);
        }
        Page page = page(businessOrderSearchDto.getPage(), queryWrapper);
        return page;
    }


    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void addBusinessOrder(ExpensesBusinessOrder expensesBusinessOrder) {
        String productionType = expensesBusinessOrder.getProductionType();
        /** 1.校验余额、扣费以及收支明细*/
        accountService.changeFromBusinessOrder(expensesBusinessOrder);
        UserInfo userInfo = UserThreadLocal.get();
        Integer companyId = userInfo.getCompanyId();
        /** 2.保存订单*/
        /** 获取业务订单号 */
        String yyyyMMddHHmmss = DateUtils.formatDate(new Date(), "yyyyMMddHHmmss");
        String orderNo = OrderConstant.BUSINESS_PRE + yyyyMMddHHmmss;
        expensesBusinessOrder.setCompanyId(companyId);
        expensesBusinessOrder.setBusinessOrderNo(orderNo);
        this.save(expensesBusinessOrder);
//        /** 3.校验并创建(更新)资源*/
//        if(expensesBusinessOrder.getStatus().equals(3)){
//            propertyService.changeFromBusinessOrder(expensesBusinessOrder);
//        }
        /** 4.套餐订单交易成功后，初始化 套餐信息*/
        if("callSetting".equals(productionType)){
//            callBaseSettingInfoService.updateFromOrder(expensesBusinessOrder);
        }
    }

    @Override
    public int checkBusinessOrder(ExpensesBusinessOrder expensesBusinessOrder) {
        QueryWrapper<ExpensesBusinessOrder> queryWrapper = new QueryWrapper<>(expensesBusinessOrder);
        int count = count(queryWrapper);
        return count;
    }

    @Override
    public ExpensesBusinessOrder getLastExpensesBusinessOrder(ExpensesBusinessOrder expensesBusinessOrder) {
        QueryWrapper<ExpensesBusinessOrder> queryWrapper = new QueryWrapper<>(expensesBusinessOrder);
        queryWrapper.orderByDesc("id");
        queryWrapper.last("limit 1");
        return getOne(queryWrapper);
    }

    /**
     * 批量废弃 没有交易成功的 业务订单
     * @param expensesBusinessOrder
     * @return
     */
    @Override
    public boolean batchAbandon(ExpensesBusinessOrder expensesBusinessOrder) {
        UpdateWrapper<ExpensesBusinessOrder> updateWrapper = new UpdateWrapper<>(expensesBusinessOrder);
        updateWrapper.ne("status",3);
        updateWrapper.set("status",400);
        boolean update = update(updateWrapper);
        return update;
    }

    /**
     * 坐席订单 交易成功
     * @param ids 坐席ID
     * @param orderId 订单ID
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void dealAgentOrder(List<Long> ids, Integer orderId) {
        ExpensesBusinessOrder businessOrder = this.getById(orderId);
        if(null == businessOrder)throw new NuoNiuException("参数错误");
        Integer orderStatus = businessOrder.getStatus();
        if(orderStatus != 1)throw new NuoNiuException("参数错误");
        String productionSpecifications = businessOrder.getProductionSpecifications();
        AgentOrderDto agentOrderDto = JSON.parseObject(productionSpecifications, AgentOrderDto.class);
        Integer number = agentOrderDto.getNumber();
        if(!number.equals(ids.size()))throw new NuoNiuException("坐席数量错误");
        agentOrderDto.setAgentIds(ids);
        businessOrder.setStatus(3);
        businessOrder.setProductionSpecifications(JSON.toJSONString(agentOrderDto));
        //更新 订单状态
        ExpensesBusinessOrder updateBusinessOrder = new ExpensesBusinessOrder();
        updateBusinessOrder.setId(businessOrder.getId());
        updateBusinessOrder.setStatus(businessOrder.getStatus());
        updateBusinessOrder.setProductionSpecifications(businessOrder.getProductionSpecifications());
        this.updateById(updateBusinessOrder);
        /** 校验并创建(更新)资源*/
        propertyService.changeFromBusinessOrder(businessOrder);
    }

    /**
     * 生成基础产品订单
     * @param crmGoodsOrder
     */
    @Override
    public void saveFromCrmGoodsOrder(CrmGoodsOrder crmGoodsOrder) {
        Integer orderType = crmGoodsOrder.getOrderType(); // 订单类型 1购买 2升级
        ExpensesBusinessOrder byCrmGoodsOrderNo = getByCrmGoodsOrderNo(crmGoodsOrder.getOrderNo());
        if(null != byCrmGoodsOrderNo)return;
        ExpensesBusinessOrder businessOrder = new ExpensesBusinessOrder();
        businessOrder.setCompanyId(crmGoodsOrder.getCompanyId());
        businessOrder.setBusinessOrderNo(crmGoodsOrder.getOrderNo());
        businessOrder.setOrderType(orderType);
        businessOrder.setOrderAmount(crmGoodsOrder.getSalePrice());
        businessOrder.setProductionType("baseProduction");
        businessOrder.setProductionId(crmGoodsOrder.getGoodsId());
        businessOrder.setProductionName(crmGoodsOrder.getGoodsName());
        businessOrder.setTimeNumber(crmGoodsOrder.getYears());
        businessOrder.setTimeUnit("年");
        businessOrder.setBusinessType(1);
        businessOrder.setStatus(3);
        businessOrder.setCreateTime(LocalDateTime.now());
        businessOrder.setCreateUserId(crmGoodsOrder.getCreate_user_id());
        businessOrder.setPayTime(LocalDateTime.now());
        businessOrder.setPayUserId(crmGoodsOrder.getCreate_user_id());
        businessOrder.setPaymentType(1);
        /** 1.校验余额、扣费以及收支明细*/
        try {
            accountService.changeFromBusinessOrder(businessOrder);
//            crmGoodsOrderService.updateOrder(crmGoodsOrder.getId().toString(),3);
        }catch (Exception e ){
            //交易失败
            businessOrder.setStatus(0);
        }
        this.save(businessOrder);
    }

    @Override
    public ExpensesBusinessOrder getByCrmGoodsOrderNo(String crmGoodsOrderNo) {
        QueryWrapper<ExpensesBusinessOrder> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("business_order_no",crmGoodsOrderNo);
        List<ExpensesBusinessOrder> list = list(queryWrapper);
        if(list.size() > 0)return list.get(0);
        return null;
    }

    @Override
    public ExpensesBusinessOrder getByCrmGoodsOrderId(Long orderId) {
        UserInfo userInfo = UserThreadLocal.get();
        Integer companyId = userInfo.getCompanyId();
        QueryWrapper<ExpensesBusinessOrder> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("company_id",companyId);
        queryWrapper.eq("id",orderId);
        queryWrapper.last("LIMIT 1");
        return getOne(queryWrapper,false);
    }
}
